/*
 *  +----------------------------------------------------------------------
 *  | sophon [ A FAST GAME FRAMEWORK ]
 *  +----------------------------------------------------------------------
 *  | Copyright (c) 2023-2029 All rights reserved.
 *  +----------------------------------------------------------------------
 *  | Licensed ( http:www.apache.org/licenses/LICENSE-2.0 )
 *  +----------------------------------------------------------------------
 *  | Author: jqiris <1920624985@qq.com>
 *  +----------------------------------------------------------------------
 */

use chrono::{DateTime, Local};

use super::*;

#[derive(Debug, Default, Clone)]
pub struct LogLocation {
    pub log_file: String,
    pub log_line: u32,
}

#[derive(Debug, Default, Clone)]
pub struct LogItem {
    pub log_level: LogLevel,
    pub allow_level: LogLevel,
    pub log_runtime: bool,
    pub time_format: String,
    pub log_time: DateTime<Local>,
    pub log_loc: Option<LogLocation>,
    pub log_txt: String,
    pub log_suffix: String, //日志后缀
}

impl LogItem {
    pub fn log_format(&self) -> String {
        let log_txt;
        if self.log_suffix.is_empty() {
            if let Some(loc) = &self.log_loc {
                log_txt = format!(
                    "[{} {}] {} [file:{} line:{}]",
                    to_level_str(&self.log_level),
                    self.log_time.format(self.time_format.as_ref()),
                    self.log_txt,
                    loc.log_file,
                    loc.log_line
                );
            } else {
                log_txt = format!(
                    "[{} {}] {}",
                    to_level_str(&self.log_level),
                    self.log_time.format(self.time_format.as_ref()),
                    self.log_txt,
                );
            }
        } else {
            if let Some(loc) = &self.log_loc {
                log_txt = format!(
                    "[{} {}] {} [{} file:{} line:{}]",
                    to_level_str(&self.log_level),
                    self.log_time.format(self.time_format.as_ref()),
                    self.log_txt,
                    self.log_suffix,
                    loc.log_file,
                    loc.log_line
                );
            } else {
                log_txt = format!(
                    "[{} {}] {} [{}]",
                    to_level_str(&self.log_level),
                    self.log_time.format(self.time_format.as_ref()),
                    self.log_txt,
                    self.log_suffix,
                );
            }
        }
        log_txt
    }

    pub fn set_log_loc(&mut self, loc: LogLocation) {
        self.log_loc = Some(loc);
    }
    pub fn print_runtime(&self) -> bool {
        return self.log_runtime || self.log_level <= LogLevel::ERROR;
    }
}

unsafe impl Sync for LogLocation {}

unsafe impl Send for LogLocation {}

unsafe impl Sync for LogItem {}

unsafe impl Send for LogItem {}
